﻿using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Abp.Authorization;
using Abp.Authorization.Users;
using Abp.MultiTenancy;
using Abp.Runtime.Security;
using Abp.UI;
using SOEI.Solution.Authentication.External;
using SOEI.Solution.Authentication.JwtBearer;
using SOEI.Solution.Authorization;
using SOEI.Solution.Authorization.Users;
using SOEI.Solution.Models.TokenAuth;
using SOEI.Solution.MultiTenancy;
using Microsoft.AspNetCore.Http;
using System.IO;
using SOEI.Solution.FileUpLoader.DomainService;
using SOEI.Solution.FileUpLoader.Configuration;
using Abp.Timing;
using SOEI.Solution.Models.FileHelper;
using SOEI.Solution.FileUpLoader;
using Microsoft.AspNetCore.Hosting;
using System.Drawing;
using ThirdParty.ESignClient;
using SOEI.Solution.Helper;

namespace SOEI.Solution.Controllers
{
	/// <summary>
	/// 【扩展模块】  <br/>
	/// 【功能描述】  ：文件上传辅助接口<br/>
	/// 【创建日期】  ：2020.08.27 <br/>
	/// 【开发人员】  ：static残影<br/>
	///</summary>
	[Route("api/[controller]/[action]")]
	public class FileHelperController : SolutionControllerBase
	{
		private readonly LogInManager _logInManager;

		private readonly IAttachManager _attachManager;

		private readonly UpLoaderConfiguration _configuration;

		public IHostingEnvironment _HostingEnvironment;

		private readonly IESignManager _ESignManager;

		public FileHelperController(
			LogInManager logInManager,
			UpLoaderConfiguration configuration,
			IAttachManager attachManager,
			IHostingEnvironment HostingEnvironment,
			IESignManager ESignManager
		)
		{
			_logInManager = logInManager;
			_attachManager = attachManager;
			_configuration = configuration;
			_HostingEnvironment = HostingEnvironment;
			_ESignManager = ESignManager;
			this.InitialStructure();
		}

		/// <summary>
		/// 根据当前日期生成目录名称
		/// </summary>
		protected string GetDirectoryName
		{
			get
			{
				var p1 = Clock.Now.ToString("yyyyMM");
				var p2 = Clock.Now.ToString("dd");
				var path = Path.Combine(p1, p2);
				return path;
			}
		}

		/// <summary>
		/// 获取新的文件名称
		/// </summary>
		/// <param name="ExtName">原始扩展名称</param>
		/// <returns></returns>
		//protected string GetNewFileName(string ExtName) 
		//{
		//	var p1 = Clock.Now.ToString("yyyyMMddHHmmssms");
		//	return string.Format("{0}{1}", p1, ExtName);
		//}

		/// <summary>
		/// 【公共服务】 文件上传  Exp: {2286b2b0-ebe7-42cb-939f-a3610f25cfb0}
		/// </summary>
		/// <param name="ModelsID">模块Guid</param>
		/// <param name="file"></param>
		/// <returns></returns>
		[HttpPost]
		public async Task<ObjectResult> Uploader(Guid ModelsID, IFormFile file)
		{
			if (Guid.Empty.Equals(ModelsID))
			{
				throw new UserFriendlyException("文件的模块编号不能为空！");
			}

			// 检查文件
			this.FileChecker(file);
			//1. 文件名称重新进行文件编码根据GUID方式
			//2. 根据文件情况创建Attach附件实体
			//3. 保存文件
			//4. 保存实体

			// 保存数据
			var AttachEntity =  await this.Save(ModelsID, file);

			await this._attachManager.CreateAsync(AttachEntity);

			//return string.Empty;
			return Ok(new { 
				Attach= AttachEntity
			});
		}

		/// <summary>
		/// 身份证上传，自动带OCR识别功能
		/// </summary>
		/// <param name="ModelsID"></param>
		/// <param name="file"></param>
		/// <returns></returns>
		[HttpPost]
		public async Task<ObjectResult> IDCardUpLoader(Guid ModelsID, IFormFile file)
		{
			if (Guid.Empty.Equals(ModelsID))
			{
				throw new UserFriendlyException("文件的模块编号不能为空！");
			}
			this.FileChecker(file);
			// 保存数据
			var AttachEntity = await this.Save(ModelsID, file);
			AttachEntity.FileType = "身份证";
			// 创建数据库保存文件
			await this._attachManager.CreateAsync(AttachEntity);
			// 
			var data = string.Empty;
			using (Stream stream = file.OpenReadStream())
			{
				data = Base64Convert.FileToBase64(stream);
			}

			var IDModel = await this._ESignManager.OCR_IDCard(data);

			return Ok(new
			{
				Attach = AttachEntity,   // 文件对象
				ResultModel = IDModel        // 识别结果
			});
		}

		/// <summary>
		/// 【公共服务】 批量文件上传  Exp: {2286b2b0-ebe7-42cb-939f-a3610f25cfb0}
		/// </summary>
		/// <param name="ModelsID"></param>
		/// <param name="file"></param>
		/// <returns></returns>
		//[HttpPost]
		//public async Task<IActionResult> Uploaders(Guid ModelsID, List<IFormFile> file)
		//{
		//	if (Guid.Empty.Equals(ModelsID))
		//	{
		//		throw new UserFriendlyException("文件的模块编号不能为空！");
		//	}
		//	if (file.Count == 0) {
		//		throw new UserFriendlyException("上传文件不能为空！");
		//	}

		//	long size = file.Sum(f => f.Length); // 上传文件的总大小

		//	foreach (var formFile in file)
		//	{
		//		// 保存数据
		//		var AttachEntity = await this.Save(ModelsID, formFile);
		//		// 创建数据库
		//		await this._attachManager.CreateAsync(AttachEntity);
		//	}
		//	return Ok(new { count = file.Count, size });
		//}

		/// <summary>
		/// 文件浏览
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		[HttpGet]
		public async Task<IActionResult> Review(long id)
		{
			// 数据库中查找
			var AttachEntity = await this._attachManager.FindByIdAsync(id);
			
			var root = _configuration.RootPath;

			var finalyFilePath = Path.Combine(root, AttachEntity.Path);
			// 读取文件
			var buffer = System.IO.File.ReadAllBytes(finalyFilePath);
			// 返回给前端下载
			return File(buffer, AttachEntity.ContentType, AttachEntity.FileName);
		}

		/// <summary>
		/// 文件浏览缩略图
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		[HttpGet]
		public async Task<IActionResult> ReviewThumbnail(long id) 
		{
			// 数据库中查找
			var AttachEntity = await this._attachManager.FindByIdAsync(id);

			var root = _configuration.RootPath;

			var finalyFilePath = Path.Combine(root, AttachEntity.Path);

			// 获取文件流对象
			// var image = Image.FromFile(finalyFilePath);

			// 读取文件
			var buffer = System.IO.File.ReadAllBytes(finalyFilePath);
			// 返回给前端下载
			return File(buffer, AttachEntity.ContentType, AttachEntity.FileName);
		}

		/// <summary>
		/// 下载指定编号的附件
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		[HttpPost]
		public async Task<ActionResult> DownLoad(long id) {
			// 数据库中查找
			var AttachEntity = await this._attachManager.FindByIdAsync(id);
		
			var root = _configuration.RootPath;

			var finalyFilePath = Path.Combine(root, AttachEntity.Path);
			// 读取文件
			var buffer = System.IO.File.ReadAllBytes(finalyFilePath);
			// 返回给前端下载
			//return PhysicalFile(finalyFilePath, AttachEntity.ContentType);
			return File(buffer, AttachEntity.ContentType, AttachEntity.FileName);
		}

		/// <summary>
		/// 获取指定编号的文件信息
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		[HttpPost]
		public async Task<ObjectResult> FindUploadInfo(long id)
		{
			if (!await this._attachManager.IsExistAsync(id)) {
				throw new UserFriendlyException("指定文件不存在，或者已经删除！");
			}
			// 数据库中查找
			var AttachEntity = await this._attachManager.FindByIdAsync(id);
			return Ok(AttachEntity);
		}

		/// <summary>
		/// 删除文件
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		[HttpPost]
		public async Task<ObjectResult> Remove(long id)
		{
			// 如果存在进行物理删除
			if (await this._attachManager.IsExistAsync(id)) {
				var AttachEntity = await this._attachManager.FindByIdAsync(id);
				// 删除数据库文件
				await this._attachManager.DeleteAsync(id);
				// 删除物理文件
				var root = _configuration.RootPath;
				var finalyFilePath = Path.Combine(root, AttachEntity.Path);
				System.IO.File.Delete(finalyFilePath);
			}

			return Ok("删除完成！");
		}

		#region -------------------------------------------------辅助方法------------------------------------------------
		/// <summary>
		/// 物理保存文件
		/// </summary>
		/// <param name="ModelsID"></param>
		/// <param name="file"></param>
		protected async Task<Attach> Save(Guid ModelsID, IFormFile file)
		{

			var root =  _configuration.RootPath;
			var FileOriginName = file.FileName; // 原始文件名
			var Extension = Path.GetExtension(FileOriginName);//文件扩展名

			var NewFileName = this._attachManager.GetNewFileName(Extension);
			var VirtualPath = Path.Combine(GetDirectoryName, NewFileName);
			var finalyFilePath = Path.Combine(root, VirtualPath);
				
			var AttachEntity = new Attach
			{
				ContentType = file.ContentType,
				Size = file.Length,
				FileName = FileOriginName, // 原始文件名称
				Path = VirtualPath,       // 实际文件路径
				Extension = Extension,
				ModuleID = ModelsID
			};
			
			//1. 文件名称重新进行文件编码根据GUID方式
			//2. 根据文件情况创建Attach附件实体
			//3. 保存文件
			//4. 保存实体
			using (Stream stream = file.OpenReadStream())
			{
				using (FileStream targetFileStream = new FileStream(finalyFilePath, FileMode.OpenOrCreate))
				{
					await stream.CopyToAsync(targetFileStream);
				}
			}
			return AttachEntity;
		}

		/// <summary>
		/// 初始化保存目录接口(目录不存在会自动创建一个)
		/// </summary>
		private void InitialStructure()
		{
			// 判断目录是否存在不存在则创建一个
			var root = Path.Combine(_configuration.RootPath, GetDirectoryName);
			var info = new DirectoryInfo(root);
			if (!info.Exists)
			{
				info.Create();
			}
		}

		

		/// <summary>
		/// 检查一下文件是否可用
		/// </summary>
		/// <param name="file"></param>
		protected void FileChecker(IFormFile file)
		{
			if (file is null)
			{
				throw new UserFriendlyException("文件不能为空！");
			}
			var Extension = Path.GetExtension(file.FileName).Trim('.');//文件扩展名

			if (!this._configuration.Extension.Contains(Extension))
			{
				throw new UserFriendlyException("上传的文件类型不被支持，请检查！");
			}
		}
		#endregion
	}
}
